Skip to main content

19 HTTP的缓存控制

服务器的缓存控制

  1. 浏览器发现缓存无数据,于是发送请求,向服务器获取资源;
  2. 服务器响应请求,返回资源,同时标记资源的有效期;
  3. 浏览器缓存资源,等待下次重用。

服务器标记资源有效期使用的头字段是 Cache-Control ,里面的值 max-age=30 就是资源的有效时间,相当于告诉浏览器这个页面只能缓存 30 秒,之后就算是过期不能用。

  • no-store:不允许缓存,用于某些变化非常频繁的数据,例如秒杀页面;
  • no-cache:可以缓存,但在使用之前必须要去服务器验证是否过期,是否有最新的版本;
  • must-revalidate:如果缓存不过期就可以继续使用,但过期了如果还想用就必须去服务器验证。

客户端的缓存控制

请求 - 应答的双方都可以用这个字段进行缓存控制,互相协商缓存的使用策略。

点击页面刷新按钮时,浏览器会在请求头里加一个 Cache-Control: max-age=0,浏览器就不会使用缓存,而是向服务器发请求。服务器看到 max-age=0,也就会用一个最新生成的报文回应浏览器。

Ctrl+F5 的强制刷新,其实是发了一个 Cache-Control: no-cache,含义和 max-age=0 基本一样,通常两者的效果是相同的。

用最基本的请求头

条件请求

浏览器用 Cache-Control 做缓存控制只能刷新数据,而且使用前还必须要去服务器验证是否是最新版。

浏览器可以用两个连续的请求组成验证动作:先是一个 HEAD,获取资源的修改时间等元信息,然后与缓存数据比较,如果没有改动就使用缓存,节省网络流量,否则就再发一个 GET 请求,获取最新的版本。

两个请求网络成本太高,HTTP 协议定义了一系列 If 开头的条件请求字段,专门用来检查验证资源是否过期,把两个请求才能完成的工作合并在一个请求里做。验证的责任也交给服务器。

if-Modified-Since 和 If-None-Match:第一次的响应报文预先提供 Last-modified 和 ETag,第二次请求时就可以带上缓存里的原值,验证资源是否是最新的。如果资源没有变,服务器就回应一个 304 Not Modified,表示缓存依然有效,浏览器就可以更新一下有效期并使用缓存。

Last-modified:文件的最后修改时间。

ETag:实体标签(Entity Tag),资源的一个唯一标识,用来解决修改时间无法准确区分文件变化的问题。

  • 文件在一秒内修改了多次
  • 文件定期更新,但有时会是同样的内容,实际上没有变化